package main;

import java.awt.BorderLayout;
import java.awt.Font;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import javax.swing.JLabel;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;


public class View extends JFrame {

	private static final long serialVersionUID = 5674304232187185106L;
	private InetAddress ip;
	private JLabel info1,info2,info3, connectedTo;
	private Choice choice = null;
	private JPanel contentPane;
	private Controller cont;
	private boolean connect = true;
	private JButton playerRock, playerPaper, playerScissors, connectTo;

	/**
	 * Called when opponent tries to connect. Generates alert screen asking if user is interested.
	 * @param inetaddress
	 * @return true if user wants to play, otherwise false
	 */
	public boolean askForAcceptance(InetAddress inetaddress){
		int answer = JOptionPane.showConfirmDialog(null, inetaddress.toString() + " wants to face you in combat. Accept?", "Want to play?", JOptionPane.YES_NO_OPTION);
		if (answer == JOptionPane.YES_OPTION){
			connectedTo.setText( "Connected to " + inetaddress.toString());
			gameMessage("Opponent is waiting for your choice...");
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Update score is to be called after each round
	 * Sets appropriate labels and makes buttons clickable
	 */
	public void updateScore(String msg, int userScore, int opponentScore){
		info2.setText(userScore + " - " + opponentScore);
		info3.setText(msg);
		toggleButtons(true); 
	}
	
	/**
	 * To be called when games are ended
	 */
	public void resetLabels(){
		info2.setText("0 - 0");
		info3.setText(" ");
		gameMessage("Click connect to get going");
		connectedTo.setText("Not connected");
	}
	
	
	/**
	 * Dialog error message - called on lost connection etc.
	 * @param s message to be displayed
	 */
	public void errorMessage(String s){
		JOptionPane.showMessageDialog(null, s, "Error", JOptionPane.ERROR_MESSAGE);
	}
	
	
	/**
	 * Update gameMessageLabel (info1) with text
	 * @param s
	 */
	public void gameMessage(String s){
		info1.setText(s);
	}
	
	
	/**
	 * Set Rock, paper, scissors buttons to clickable or not clickable 
	 * @param enabled
	 */
	public void toggleButtons(boolean enabled)
	{
		playerRock.setEnabled(enabled);
		playerPaper.setEnabled(enabled);
		playerScissors.setEnabled(enabled);
	}
	/**
	 * Set connect button to "Connect" or "Disconnect"
	 * @param connect
	 */
	public void setConnectButton(boolean connect)
	{
		this.connect = connect;
		if (connect)
			connectTo.setText("Connect");
		else
			connectTo.setText("Disconnect");
	}

	/**
	 * Create the frame and add controller instance 
	 */
	public View() {
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 400, 250);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(new BorderLayout(0, 0));
		
		JPanel center = new JPanel();
		contentPane.add(center, BorderLayout.CENTER);
		center.setLayout(new GridLayout(2, 1, 0, 0));
		
		
		try {
			ip = InetAddress.getLocalHost();
		} catch (UnknownHostException e2) {}
		
		JPanel infoPanel1 = new JPanel();
		center.add(infoPanel1);
		infoPanel1.setLayout(new BorderLayout(0, 0));
		
		info1 = new JLabel("Click connect to get going");
		info1.setBorder(BorderFactory.createTitledBorder("Status"));
		infoPanel1.add(info1, BorderLayout.NORTH);
		
		info3 = new JLabel(" ");
		info3.setBorder(BorderFactory.createTitledBorder("Game Info"));
		infoPanel1.add(info3, BorderLayout.SOUTH);
		
		JPanel infoPanel2 = new JPanel();
		center.add(infoPanel2);
		
		info2 = new JLabel("0 - 0");
		info2.setFont(new Font("SansSerif", Font.PLAIN, 50));
		//info2.setBorder(BorderFactory.createTitledBorder("Score"));
		infoPanel2.add(info2);
		
		JPanel east = new JPanel();
		contentPane.add(east, BorderLayout.WEST);
		east.setLayout(new GridLayout(3, 1, 0, 0));
		
		playerRock = new JButton("Rock");
		playerRock.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				toggleButtons(false);
				gameMessage("Waiting for opponent...");
				choice = new Choice(Choice.ROCK);
				cont.sendChoice(choice);
				
			}
		});
		east.add(playerRock);
		
		playerPaper = new JButton("Paper");
		playerPaper.setSelectedIcon(null);
		east.add(playerPaper);
		playerPaper.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				toggleButtons(false);
				gameMessage("Waiting for opponent...");
				choice = new Choice(Choice.PAPER);
				cont.sendChoice(choice);
			}
		});
		
		playerScissors = new JButton("Scissors");
		east.add(playerScissors);
		playerScissors.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				toggleButtons(false);
				gameMessage("Waiting for opponent...");
				choice = new Choice(Choice.SCISSORS);
				cont.sendChoice(choice);
			}
		});
		
		JPanel west = new JPanel();
		contentPane.add(west, BorderLayout.EAST);
		west.setLayout(new GridLayout(3, 1, 0, 0));
		
		JPanel north = new JPanel();
		contentPane.add(north, BorderLayout.NORTH);
		north.setLayout(new BorderLayout(0, 0));
		
		connectedTo = new JLabel("Not connected");
		north.add(connectedTo, BorderLayout.WEST);
		
		connectTo = new JButton("Connect");
		connectTo.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) 
			{
				if (connect)
				{
					String tmpIp= (String)JOptionPane.showInputDialog("Input ip-address of user you want to play with");
					if (tmpIp != null)
					{
						try {
							ip = InetAddress.getByName(tmpIp);
							cont.connectToGame(ip);
							toggleButtons(true);
							connectedTo.setText("Connected to " + ip.toString());
							gameMessage("Opponent is waiting for your choice...");
						} catch (UnknownHostException e1) {
							System.out.println("Invalid IP reverting to " + ip.getHostAddress());
						} catch (IOException e1) {
							e1.printStackTrace();
							cont.lostConnectionToOpponent();
						}
						connect = false;
						connectTo.setText("Disconnect");
					}
					
				} else
				{
					cont.disconnect();
					connect = true;
					connectTo.setText("Connect");
				}

			}
		});
		north.add(connectTo, BorderLayout.EAST);
		this.setResizable(false);
		toggleButtons(false);
		try {
			cont = new Controller(this);
		} catch (IOException e1) {
			e1.printStackTrace();
		}
	}
}